import React from "react";
import ReactDOM from "react-dom/client";

class Hello extends React.Component {
  componentDidMount() {
    console.log("Hello - componentDidMount");
  }

  componentDidUpdate() {
    console.log("Hello - componentDidUpdate");
  }

  /**
   * 我应该更新嘛，我要不要走更新流程呢？ render componentDidUpdate
   *    1. 接收两个参数
   *        nextProps   最新的 props
   *        nextState   最新的 state
   *    2. 需要返回一个 boolean 值 。默认没有写这个函数的时候，全部都是返回的true
   *        true      要走更新流程, 页面才会更新
   *        false     阻止更新流程, 页面就不会更新了
   *    3. 要实现，我用到的数据更新了就要更新，用不到的数据更新了，我就不更新。
   *    4. 一般不需要自己去实现。有一个React内置的组件，可以帮我们处理 PureComponent
   */
  shouldComponentUpdate(nextProps, nextState) {
    console.log("Hello - shouldComponentUpdate", nextProps, nextState);
    if (this.props.name !== nextProps.name) {
      // 我当前的 props 中的 name ，不等于你传递过来的新的 props.name 我就需要更新
      return true;
    }
    return false;
  }

  render() {
    console.log("Hello - render");
    return (
      <div>
        <h1>Hello, {this.props.name}</h1>
      </div>
    );
  }
}

class App extends React.Component {
  state = {
    person: {
      name: "张三",
      age: 18,
    },
  };

  render() {
    console.log("App - render");
    return (
      <div>
        <h1>App</h1>
        <p>姓名：{this.state.person.name}</p>
        <p>年龄：{this.state.person.age}</p>

        <button
          onClick={() => {
            this.setState({
              person: {
                ...this.state.person,
                name: "李四",
              },
            });
          }}
        >
          修改姓名为李四
        </button>

        {/* 
          age 修改之后，Hello 也会继续 render .走更新阶段的流程。但是我们 Hello 中并不需要用到age。
          如果我们控制一下 age 的改变，不让 Hello 组件 走更新流程，是不是就实现了性能优化。
        */}
        <button
          onClick={() => {
            this.setState({
              person: {
                ...this.state.person,
                age: 20,
              },
            });
          }}
        >
          修改年龄为20
        </button>

        <Hello name={this.state.person.name} />
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.querySelector("#root"));
root.render(<App />);
